`CFX_FillRenderOptions` 结构体是 PDFium 项目中用于定义路径填充选项的核心类。它封装了与路径填充相关的各种参数，确保在渲染 PDF 文档中的图形和文本时能够正确应用不同的填充规则和效果。以下是 `CFX_FillRenderOptions` 的详细解析：

### 类定义

```cpp
struct CFX_FillRenderOptions {
  // FillType defines how path is filled.
  enum class FillType : uint8_t {
    // No filling needed.
    kNoFill = 0,

    // Use even-odd or inverse even-odd algorithms to decide if the area needs
    // to be filled.
    kEvenOdd = 1,

    // Use winding or inverse winding algorithms to decide whether the area
    // needs to be filled.
    kWinding = 2,
  };

  static constexpr CFX_FillRenderOptions EvenOddOptions() {
    return CFX_FillRenderOptions(FillType::kEvenOdd);
  }
  static constexpr CFX_FillRenderOptions WindingOptions() {
    return CFX_FillRenderOptions(FillType::kWinding);
  }

  constexpr CFX_FillRenderOptions()
    : CFX_FillRenderOptions(FillType::kNoFill) {
  }

  constexpr explicit CFX_FillRenderOptions(FillType fill_type)
    : fill_type(fill_type),
    adjust_stroke(false),
    aliased_path(false),
    full_cover(false),
    rect_aa(false),
    stroke(false),
    stroke_text_mode(false),
    text_mode(false),
    zero_area(false) {
  }

  bool operator==(const CFX_FillRenderOptions& other) const {
    return fill_type == other.fill_type &&
      adjust_stroke == other.adjust_stroke &&
      aliased_path == other.aliased_path &&
      full_cover == other.full_cover && rect_aa == other.rect_aa &&
      stroke == other.stroke &&
      stroke_text_mode == other.stroke_text_mode &&
      text_mode == other.text_mode && zero_area == other.zero_area;
  }

  bool operator!=(const CFX_FillRenderOptions& other) const {
    return !(*this == other);
  }

  // Fill type.
  FillType fill_type;

  // Adjusted stroke rendering is enabled.
  bool adjust_stroke : 1;

  // Whether anti aliasing is enabled for path rendering.
  bool aliased_path : 1;

  // Fills with the sum of colors from both cover and source.
  bool full_cover : 1;

  // Rect paths use anti-aliasing.
  bool rect_aa : 1;

  // Path is stroke.
  bool stroke : 1;

  // Renders text by filling strokes.
  bool stroke_text_mode : 1;

  // Path is text.
  bool text_mode : 1;

  // Path encloses zero area.
  bool zero_area : 1;
};
```

### 主要功能

#### 1. * *填充类型 * *

-**`FillType` 枚举 * *：
- `kNoFill`：不进行填充。
- `kEvenOdd`：使用奇偶填充规则（even - odd rule），即如果从一个点到无穷远的射线穿过路径的边界的次数为奇数，则该点属于填充区域；否则不属于。
- `kWinding`：使用非零环绕数填充规则（non - zero winding rule），即根据路径的方向计算每个点的环绕数，如果环绕数非零，则该点属于填充区域。

- **静态构造函数 * *：
- `EvenOddOptions()`：返回一个使用 `kEvenOdd` 填充规则的 `CFX_FillRenderOptions` 对象。
- `WindingOptions()`：返回一个使用 `kWinding` 填充规则的 `CFX_FillRenderOptions` 对象。

#### 2. * *构造函数 * *

-**默认构造函数 * *：
- `CFX_FillRenderOptions()`：初始化为 `kNoFill`，即不进行填充。

- **带参数的构造函数 * *：
- `explicit CFX_FillRenderOptions(FillType fill_type)`：根据指定的 `fill_type` 初始化对象，并将其他布尔标志位设置为 `false`。

#### 3. * *比较运算符 * *

-**相等运算符 * *：
- `operator= = `：比较两个 `CFX_FillRenderOptions` 对象是否相等，检查所有成员变量是否相同。

- **不等运算符 * *：
- `operator! = `：通过调用 `operator= = ` 实现，返回两个对象是否不相等。

#### 4. * *布尔标志位 * *

-**`adjust_stroke`* * ：
- 是否启用调整后的描边渲染。如果启用，PDFium 会根据路径的形状调整描边的效果。

- **`aliased_path`* * ：
- 是否启用路径的抗锯齿（anti - aliasing）。如果启用，路径的边缘会更加平滑，避免锯齿效应。

- **`full_cover`* * ：
- 是否使用覆盖颜色和源颜色的总和进行填充。如果启用，填充区域的颜色将是覆盖颜色和源颜色的叠加效果。

- **`rect_aa`* * ：
- 是否对矩形路径启用抗锯齿。如果启用，矩形路径的边缘会更加平滑。

- **`stroke`* * ：
- 路径是否为描边。如果启用，路径将被描边而不是填充。

- **`stroke_text_mode`* * ：
- 是否以描边方式渲染文本。如果启用，文本将以描边的形式呈现，而不是填充。

- **`text_mode`* * ：
- 路径是否为文本。如果启用，路径将被视为文本路径，可能会应用特殊的文本渲染规则。

- **`zero_area`* * ：
- 路径是否封闭零面积。如果启用，表示路径是一个闭合但没有实际面积的路径，例如一个点或一条线。

### 实际应用

`CFX_FillRenderOptions` 在 PDFium 中主要用于以下场景：

1. * *路径填充 * *：
- 当需要填充一个复杂的路径时，`CFX_FillRenderOptions` 提供了多种填充规则（如 `kEvenOdd` 和 `kWinding`），确保路径的内部区域能够正确填充。选择合适的填充规则对于复杂的矢量图形尤为重要，因为它决定了哪些区域应该被填充。

2. * *描边和填充结合 * *：
- 通过设置 `stroke` 和 `text_mode` 标志位，可以控制路径是仅描边、仅填充，还是同时描边和填充。这对于实现复杂的图形效果非常有用，例如绘制带有轮廓的文本或图形。

3. * *抗锯齿和高质量渲染 * *：
- 通过启用 `aliased_path` 和 `rect_aa` 标志位，可以启用抗锯齿功能，使路径的边缘更加平滑，尤其是在高分辨率显示器上，这可以显著提高渲染质量。

4. * *文本渲染 * *：
- 当渲染文本时，`stroke_text_mode` 标志位允许以描边方式呈现文本，而不是填充。这对于创建特殊的文本效果（如空心字）非常有用。

5. * *特殊路径处理 * *：
- 通过设置 `zero_area` 标志位，可以处理那些封闭零面积的路径（如单个点或线条），确保它们不会被错误地填充。

6. * *性能优化 * *：
- 通过禁用不必要的选项（如 `full_cover` 或 `adjust_stroke`），可以在不需要这些效果的情况下提高渲染性能，特别是在处理大量简单路径时。

### 总结

`CFX_FillRenderOptions` 是 PDFium 中用于定义路径填充选项的关键结构体。它不仅提供了多种填充规则（如 `kEvenOdd` 和 `kWinding`），还支持描边、抗锯齿、文本渲染等多种渲染效果。通过灵活配置这些选项，PDFium 可以在不同场景下实现高质量的图形和文本渲染，同时确保性能优化。// Copyright 2020 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CORE_FXGE_CFX_FILLRENDEROPTIONS_H_
#define CORE_FXGE_CFX_FILLRENDEROPTIONS_H_

#include <stdint.h>

// Represents the options for filling paths.
struct CFX_FillRenderOptions {
  // FillType defines how path is filled.
  enum class FillType : uint8_t {
    // No filling needed.
    kNoFill = 0,

    // Use even-odd or inverse even-odd algorithms to decide if the area needs
    // to be filled.
    kEvenOdd = 1,

    // Use winding or inverse winding algorithms to decide whether the area
    // needs to be filled.
    kWinding = 2,
  };

  static constexpr CFX_FillRenderOptions EvenOddOptions() {
    return CFX_FillRenderOptions(FillType::kEvenOdd);
  }
  static constexpr CFX_FillRenderOptions WindingOptions() {
    return CFX_FillRenderOptions(FillType::kWinding);
  }

  constexpr CFX_FillRenderOptions()
      : CFX_FillRenderOptions(FillType::kNoFill) {}

  // TODO(thestig): Switch to default member initializer for bit-fields when
  // C++20 is available.
  constexpr explicit CFX_FillRenderOptions(FillType fill_type)
      : fill_type(fill_type),
        adjust_stroke(false),
        aliased_path(false),
        full_cover(false),
        rect_aa(false),
        stroke(false),
        stroke_text_mode(false),
        text_mode(false),
        zero_area(false) {}

  bool operator==(const CFX_FillRenderOptions& other) const {
    return fill_type == other.fill_type &&
           adjust_stroke == other.adjust_stroke &&
           aliased_path == other.aliased_path &&
           full_cover == other.full_cover && rect_aa == other.rect_aa &&
           stroke == other.stroke &&
           stroke_text_mode == other.stroke_text_mode &&
           text_mode == other.text_mode && zero_area == other.zero_area;
  }

  bool operator!=(const CFX_FillRenderOptions& other) const {
    return !(*this == other);
  }

  // Fill type.
  FillType fill_type;

  // Adjusted stroke rendering is enabled.
  bool adjust_stroke : 1;

  // Whether anti aliasing is enabled for path rendering.
  bool aliased_path : 1;

  // Fills with the sum of colors from both cover and source.
  bool full_cover : 1;

  // Rect paths use anti-aliasing.
  bool rect_aa : 1;

  // Path is stroke.
  bool stroke : 1;

  // Renders text by filling strokes.
  bool stroke_text_mode : 1;

  // Path is text.
  bool text_mode : 1;

  // Path encloses zero area.
  bool zero_area : 1;
};

#endif  // CORE_FXGE_CFX_FILLRENDEROPTIONS_H_
